<?php
/***************************************************************
*  Copyright notice
*
*  (c) 2005 Daniel Ptzinger (info@xaba.de)
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
 * Plugin 'Tagcloud' for the 'danp_tagcloud' extension.
 *
 * @author	Daniel Ptzinger <info@xaba.de>
 */


require_once(PATH_tslib.'class.tslib_pibase.php');
define('DANP_LIB_PATH',t3lib_extMgm::extPath("danp_libs"));

require_once(DANP_LIB_PATH.'class.tx_danplibs_helper.php');

class tx_danptagcloud_pi1 extends tslib_pibase {
	var $prefixId = 'tx_danptagcloud_pi1';		// Same as class name
	var $scriptRelPath = 'pi1/class.tx_danptagcloud_pi1.php';	// Path to this script relative to the extension dir.
	var $extKey = 'danp_tagcloud';	// The extension key.
	var $pi_checkCHash = TRUE;
	
	
	var $internal=array(); 	// holds the information for rendering and generation
	
	/* Init with help of helper class
	  	-set internal vars (combined of TS and Flexform)
	*/
	function init() {
		$helper=t3lib_div::makeInstance('tx_danplibs_helper');
		$helper->initGeneral(&$this);
		$this->internal['fontsizemin']=t3lib_div::intInRange($helper->getTSorFlexValue('fontsizemin','sDEF'),1,100,10);
		$this->internal['fontsizemax']=t3lib_div::intInRange($helper->getTSorFlexValue('fontsizemax','sDEF'),1,100,30);
		$this->internal['maxtags']=t3lib_div::intInRange($helper->getTSorFlexValue('maxtags','sDEF'),1,100,10);
		
		if (defined("SORT_LOCALE_STRING"))
            $this->SORT_FLAG=SORT_LOCALE_STRING ;	
    elseif (defined("SORT_STRING"))
            $this->SORT_FLAG=SORT_STRING;
    else
    	      $this->SORT_FLAG='';
    	      
		$this->internal['generationMode']=$helper->getTSorFlexValue('generationMode','sAdv');
		$this->internal['tagfield']=$helper->getTSorFlexValue('tagfield','sAdv');
		$this->internal['overwriteAddWhere']=$helper->getTSorFlexValue('overwriteAddWhere','sAdv');
		$this->sys_language_mode=$this->conf['sys_language_mode'];
		
		$this->conf['filterWords']=$helper->getTSorFlexValue('filterWords','sAdv');
		
		
		$this->internal['preConfiguration']=$helper->getTSorFlexValue('preConfiguration','sDEF');	
			//backward compatibility: (i moved parameter and linkPid to linkConstants.)
			if (!isset($this->conf['linkConstants.']['parameter']))
				$this->conf['linkConstants.']['parameter']=$this->conf['parameter'];
			if (!isset($this->conf['linkConstants.']['linkPid']))
					$this->conf['linkConstants.']['linkPid']=$this->conf['linkPid'];
					
		$this->internal['parameter']=$helper->getTSorFlexValue('parameter','sLink',$this->conf['linkConstants.']);	
		$this->internal['linkpid']=$helper->getTSorFlexValue('linkpid','sLink',$this->conf['linkConstants.']);	
		
		$this->internal['onlyUid']=$helper->getTSorFlexValue('uidParameter','sLink');		
	}
	
	
	/**
	 * [Main Function]
	 */
	function main($content,$conf)	{
		$this->conf=$conf;
		$this->init();
		$this->local_cObj = t3lib_div::makeInstance('tslib_cObj'); // Local cObj.

		
		//get Defaultconfiguration from TS
		if ($this->internal['preConfiguration'] != "") {
			$preConfArray=$this->conf['preConfigurations.'][$this->internal['preConfiguration'].'.'];
			if (isset($preConfArray['generationMode'])) {
				//defaultconfig is present so override if not empty: (otherwise the TS default or the Felxformsettings are used)
				if ($preConfArray['generationMode']!='')
					$this->internal['generationMode']=$preConfArray['generationMode'];
				
				if ($preConfArray['tagfield']!='')
					$this->internal['tagfield']=$preConfArray['tagfield'];
				
				if (isset($preConfArray['overwriteAddWhere']))
					$this->internal['overwriteAddWhere']=$preConfArray['overwriteAddWhere'];				
				if (isset($preConfArray['sys_language_mode']))
				 $this->sys_language_mode=$preConfArray['sys_language_mode'];
					
				//override linkparams only if they arenot set yet in ff or ts
				if ($this->internal['parameter']=='')
					$this->internal['parameter']=$preConfArray['parameter'];
				if ($this->internal['linkpid']=='')
					$this->internal['linkpid']=$preConfArray['linkpid'];
					
				//override general typolinkconf:
				if ($preConfArray['tagTypolinkPreconfiguration.']!='')
					$this->conf['tagTypolinkPreconfiguration.']=$preConfArray['tagTypolinkPreconfiguration.'];
			}
		}

		 
		// calculate the tagArray:
			$tagfields=t3lib_div::trimExplode(":",$this->internal['tagfield']);
			$from_table=$tagfields[0];
			$field=$tagfields[1];
				
		switch ($this->internal['generationMode']) {
			case 'fromDBField':
				$allTags=$this->getTagCloudInfosFromNestedField($from_table,$field,$this->internal['maxtags']);
				
			break;
			case 'fromDBColumn':		
				$allTags=$this->getTagCloudInfosFromColumn($from_table,$field,$this->internal['maxtags']);
			break;
			default: 
				$allTags=array();
			break;
		}
				
		
		
		
		//Output generation:
		$content=$this->renderTagCloudFromTagCloudInfoArray($allTags);
		
		return $this->local_cObj->stdWrap($content,$this->conf['all_stdWrap.']);
	}
	/* returns array with infos for tagcloud
		'tags'=>array(<name>=>count) (sorted by <name>)
		'maxCount'
		'minCount'
	*/
	function getTagCloudInfosFromNestedField($from_table,$field,$maxItems) {
		$where_clause=$this->help_getAddWhere($from_table);
		//if uidParameter is set and there is a valid number submitted => then only select this record			
		if ($this->conf['onlyUid']) {			
			 $uid=intval($this->local_cObj->cObjGetSingle($this->conf['onlyUid'],$this->conf['onlyUid.']));
				if ($uid>0) {
					$where_clause="uid=$uid";
				}			
		}
		
		$allTags=array();
		$res=$GLOBALS['TYPO3_DB']->exec_SELECTquery('*',$from_table,$where_clause,'','','');
		//echo $GLOBALS['TYPO3_DB']->SELECTquery('*',$from_table,$where_clause,'','','');
		while ($row=$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
			
			if ($this->sys_language_mode=='content_fallback' && $GLOBALS['TSFE']->sys_language_content) {
					$row = $GLOBALS['TSFE']->sys_page->getRecordOverlay($from_table, $row, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL, '');					
			}
			
			//explode by , and space
			$temptags=t3lib_div::trimExplode(",",$row[$field],TRUE);
			foreach ($temptags as $tag) {
				$tags=t3lib_div::trimExplode(" ",$tag,TRUE);
				foreach ($tags as $tag) {
					$allTags[$tag]++;
				}
			}
		}
		$allTags=$this->_filterTags($allTags);
		$allTags=$this->_cutToMaxTags($allTags);
		$return=$this->_getMinAndMax($allTags);
		$this->_sortTagArray($allTags);
		
		$return['tags']=&$allTags;
							
								
		return $return;
	}
	function _getMinAndMax($allTags) {
		//get min and max and cut to maxtags:
		arsort($allTags);
		reset($allTags);
		$max=current($allTags);		
		$min=end($allTags);
		$return=array('maxCount'=>$max,
				'minCount'=>$min);
		return $return;
	}
	function _filterTags($allTags) {
		$filterTags=t3lib_div::trimExplode(',',$this->conf['filterWords']);
		$filtered=array();
		foreach ($allTags as $k=>$v) {
			if (!in_array($k,$filterTags)) {
				$filtered[$k]=$v;
			}
		}
		return $filtered;
	}
	function _cutToMaxTags($allTags) {
		//get min and max and cut to maxtags:
		arsort($allTags);
		reset($allTags);				
		$count=count($allTags);		
		if ($count > $this->internal['maxtags']) {
			$allTags=array_slice($allTags,0,$this->internal['maxtags']);						
		}
		return $allTags;
	}
	
	function _sortTagArray(&$allTags) {
		//sort by tagname
		ksort($allTags, $this->SORT_FLAG);
	
	}
	
	function getTagCloudInfosFromTagTable($from_table,$tag_field,$count_field,$maxItems) {

		$where_clause=$this->help_getAddWhere($from_table);		
		
		$allTags=array();
		$res=$GLOBALS['TYPO3_DB']->exec_SELECTquery('*',$from_table,$where_clause,'',$count_field,'0,'.$maxItems);
		$firstRound=TRUE;
		while ($row=$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
				if ($this->sys_language_mode=='content_fallback' && $GLOBALS['TSFE']->sys_language_content) {
					$row = $GLOBALS['TSFE']->sys_page->getRecordOverlay($from_table, $row, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL, '');					
				}
				if ($firstRound) {
					$firstRound=FALSE;
					$min=$max=$row[$count_field];
				}
				$allTags[$row[$tag_field]]=$row[$count_field];
				if ($row[$count_field] > $max)
					$max=$row[$count_field];
				if ($row[$count_field] < $min)
					$min=$row[$count_field];
		}
		$allTags=$this->_filterTags($allTags);
		//sort by tagname
		$this->_sortTagArray($allTags);
		
		$return=array('tags'=>&$allTags,
								'maxCount'=>$max,
								'minCount'=>$min);
		return $return;
	}
	
	function help_getGPvalue($v) {
		$gpKeys=t3lib_div::trimExplode('|',$this->internal['onlyUid'],true);
		
			$value=t3lib_div::_GP($gpKeys[0]);
			
			unset($gpKeys[0]);
			foreach ($gpKeys as $key) {
				if (is_array($value))
					$value=$value[$key];
			}
			
			return $value;
	}
	function help_getAddWhere($from_table) {
	
		if($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'pages', 'sDEF')=='') $this->internal['pidList']=$this->conf['pidList']!=''?$this->conf['pidList']:$this->internal['pidList'];
		$this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'recursive', 'sDEF');
		if ($this->internal['overwriteAddWhere']!='') {			
			$where_clause=$this->internal['overwriteAddWhere'];
			$where_clause= str_replace('%table%',$from_table,$where_clause);
			$where_clause= str_replace('%pidlist%',$this->internal['pidList'],$where_clause);
		}
		else {
			$where_clause =$from_table.'.pid IN ('.$this->internal['pidList'].')';
			$where_clause .= $this->local_cObj->enableFields($from_table);		
			
			if ($this->sys_language_mode=='strict' && isset($GLOBALS['TSFE']->sys_language_content)) {
				$where_clause .=' AND sys_language_uid='.intval($GLOBALS['TSFE']->sys_language_content);
			}
			elseif ($this->sys_language_mode !='' && isset($GLOBALS['TSFE']->sys_language_content)) {
				$where_clause .=' AND sys_language_uid IN (0,-1)';
			}
		}
		return $where_clause;
	}
	
	function getTagCloudInfosFromColumn($from_table,$tag_field,$maxItems) {
		$where_clause=$this->help_getAddWhere($from_table);	
				
		$allTags=array();
		$res=$GLOBALS['TYPO3_DB']->exec_SELECTquery($tag_field.', count('.$tag_field.') as count',$from_table,$where_clause,$tag_field,'count','0,'.$maxItems);
		$firstRound=TRUE;
		while ($row=$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
				if ($firstRound) {
					$firstRound=FALSE;
					$min=$max=$row['count'];
				}
				$allTags[$row[$tag_field]]=$row['count'];
				if ($row['count'] > $max)
					$max=$row['count'];
				if ($row['count'] < $min)
					$min=$row['count'];
		}
		$allTags=$this->_filterTags($allTags);
		//sort by tagname
		ksort($allTags, $this->SORT_FLAG);
		
		$return=array('tags'=>&$allTags,
								'maxCount'=>$max,
								'minCount'=>$min);
		return $return;
	}
	/*
	* @param Array with Informations for the tagcloud (tags,maxCount,minCount)
	* @return The rendered Tagcloud
	*/
	function renderTagCloudFromTagCloudInfoArray($allTags) {
		
		$fontInterval=$this->internal['fontsizemax']-$this->internal['fontsizemin'];
		
		$countInterval=$allTags['maxCount']-$allTags['minCount'];
		//print_r($allTags);
		/* size calculation:
		* maxSize := maxCount
		* minSize := minCount
		* => fontsize=minSize+differenz
		* differenz := tagcount
		* (fontInterval) := (countInterval)
		*/
		if ($countInterval >0)
			$ratio=$fontInterval/$countInterval;
		else
			$ratio=0;
			
		//TYPOLINK Konfiguration:
		$typolinkConf=$this->conf['tagTypolinkPreconfiguration.'];		
		if ($this->internal['linkpid']=='')
			$this->internal['linkpid']=$GLOBALS['TSFE']->id;			
		if ($typolinkConf['parameter'] !='')
		 $typolinkConf['parameter']=str_replace('%linkpid%',$this->internal['linkpid'],$typolinkConf['parameter']);
		else
			$typolinkConf['parameter']=$this->internal['linkpid'];		
		$originAddParams=str_replace('%parameter%',$this->internal['parameter'],$typolinkConf['additionalParams']);
		//set default
		if ($originAddParams=='') {
			$originAddParams='&'.$this->internal['parameter'].'=%tag%';
		}
		
		
		if (is_array($allTags['tags'])) {
			foreach ($allTags['tags'] as $tagname => $tagcount) {
				$size=round($this->internal['fontsizemin']+(($tagcount-$allTags['minCount'])*$ratio),2);
				$fontMeasure=$this->conf['fontSizeMeasure']?$this->conf['fontSizeMeasure']:'px';
				$style='style="font-size:'.$size.$fontMeasure.'"';				
				$typolinkConf['additionalParams']=str_replace('%tag%',rawurlencode($tagname),$originAddParams);				
				//add class:
				$className=' cloud_'.$size;
				if ($tagcount==$allTags['maxCount']) {
					$className.=' cloud_max';
				}
				if ($tagcount==$allTags['maxCount']) {
					$className.=' cloud_min';
				}
				if ($countInterval>0) {				
					$classLevelCount=$this->conf['classLevelCount']?$this->conf['classLevelCount']:'5';
					$level=ceil((($tagcount-$allTags['minCount'])*$classLevelCount)/$countInterval);
					$className.=' cloudlevel_'.$level;
				}
				$class=' class="'.$className.'"';
				$typolinkConf['ATagParams']=$style.$class;
				
				$tagname=$this->local_cObj->typolink($tagname,$typolinkConf);
				$content.=$this->local_cObj->stdWrap($tagname,$this->conf['tag_stdWrap.'])."\n";
				
			}
		}
		return $content;
	}
	
}



if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/danp_tagcloud/pi1/class.tx_danptagcloud_pi1.php'])	{
	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/danp_tagcloud/pi1/class.tx_danptagcloud_pi1.php']);
}

?>